package com.tedu.api.map;

import org.junit.Test;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

import static java.time.chrono.JapaneseEra.values;

/**包位置：java.util
 * Map与Collection同等级顶级接口
 * Map映射接口
 * 作用：一个元素由两个对象构成，分别为Key【键】和Value【值】构成
 *    获取数据；采取键取值，通常与数据库搭配，获取字段下的值
 *特点：无序，无下标，键不可以重复【唯一性】，值可以重复
 *
 * Map实例化【创建】对象---实现类；
 * HashMap【常用】：由哈希算法底层实现，储存性能快，键可以存null通过键找值
 * LinkedHashMap【不常用】：用于日志记录按照时间顺序
 * TreeMap【不用】  性能：插入删除非常慢，多线程不安全，占用内存
 * Hashtable【不用】 不安全：插入删除非常慢
 *           【算法：哈希算法】
 * Hashtable被ConcurrentHashMap取代
 * ConcurrentHashMap【较为常用】；学习多线程
 *
 * 重点：Map接口中方法【Map接口方法与HashMap方法类似】
 *
 */
public class MapAPI {
  @Test
    public void testMap(){
      //创建Map映射接口---多态    键--->值  id--20041008
      Map<Object,String> map=new HashMap<>();
      //键-->值  添加元素：K-V
      /**
       * put("键","值")  返回值V value 值
       * 作用；存键值对形态一组数据
       */
      map.put("西游记","孙悟空");
      map.put("红楼梦","林黛玉");
      map.put("三国","曹操");
      map.put("水浒传","宋江");
      System.out.println("map映射存储数据"+map);
      /**
       * get【E e】 根据键找到对应值 返回值V value
       * remove(K key) 通过Key删除一组键值对
       * size() 获取map元素总数 返回值 int
       *
       */
      //找到map集合中 宋江的元素---V value 值
         String songjiang=map.get("水浒传");
      System.out.println("通过键赋值："+songjiang);
      //get()键不存在--返回值的默认值：基本类型，引用类型：null值
      String caocao=map.get("三国");
      System.out.println("通过键赋值："+caocao);
      map.remove("三国");
      System.out.println("删除后映射："+map);
    System.out.println("获取map元素总数"+map.size());
    /**
     * containsKey()  返回值：boolean
     * 作用：判断map中元素  “对象：键” 是否存在
     * containsValue() 返回值：boolean
     * 作用：判断map中元素 “对象：值”  是否存在
     */
    boolean bk=map.containsKey("红楼梦");
    boolean bv=map.containsValue("武松");

  }

  /**
   * map元素遍历   键--->值
   * keySet()      获取map元素中所有的键
   * values()      获取map元素中所有的值
   * entrySet()    获取map元素中所有的键与值
   */
  @Test
  public void testKVE(){
    //创建Map映射集合
    Map<Object,String> map=new HashMap<>();
    map.put("墨","那英");map.put("告白气球","周杰伦");
    map.put("套马杆","乌兰图雅");map.put("丑八怪","薛之谦");
    //1.获取map集合元素中 键 数据 keySet() 返回值：Set集合
    Set<Object> sets=map.keySet();
    //1.2遍历从map元素中获取的键--数据
    for(Object keys:sets){
      System.out.println("输出map元素中："+keys);
    }
    //2.获取map集合元素中 值 数据 values() 返回值：Collection
    Collection<String> cs=map.values();
    //2.2遍历从map元素中获取的键--数据
    for (String values:cs){
      System.out.println("输出map元素中："+values);
    }
    //3.获取map集合元素【entrys】中 数据：键与值 entrySet()
    //返回值：Set<Map.Entry<K,V>>
    //Map.Entry<K,V>  保存map元素一组数据，表示：一组entry
    Set<Map.Entry<Object,String>> entrys=map.entrySet();
    //获取map映射集合所有元素【entry】
    //3.1遍历map所有的键与值【所有entry/元素/数据--成对】
    for (Map.Entry<Object,String> entry:entrys){
      //3.2获取键   getKey  注意：类型
     Object keys=entry.getKey();
      //3.3获取值   getValue 注意：类型
      String values= entry.getValue();
      //3.4 打印
      System.out.println(keys+""+values);
    }
  }
/**
 * forEach()  遍历map中所有  对元素/entry
 * 理解：for+entrySet()集合=forEach()
 * BiConsumer接口参数 传入
 *理解：针对map储存问题--封装接口--提供方法：accept() 所有entry
 */
@Test
  public void testForEach(){
  //创建Map映射集合
  Map<Object,String> map=new HashMap<>();
  map.put("墨","那英");map.put("告白气球","周杰伦");
  map.put("套马杆","乌兰图雅");map.put("丑八怪","薛之谦");
  //Map映射集合--提供一套方法：forEach()
  map.forEach(new BiConsumer<Object, String>() {
    //accept(K,V)方法：获取到Entry中--每组entry
    //K--键  V--值
    public void accept(Object key, String value){
      System.out.println(key+""+value);
    }
  });
}
/**
 /**
 * HashMap 映射集合
 * HashMap中方法基本与Map方法一致
 * putIfAbsent()
 * 作用： 用来给HashMap映射集合存入【Entry/一组数据：一组键值】
 *      如果存入一组数据，不存在的键，插入HashMap
 *                     存在的键，不插入HashMap
 *      哈希算法--唯一性
 */
@Test
  public void testHashMap(){
  //创建Map映射集合
  Map<Object,String> map=new HashMap<>();
  map.putIfAbsent("","");
  map.put("墨","那英");map.put("告白气球","周杰伦");
  map.put("套马杆","乌兰图雅");map.put("丑八怪","薛之谦");
  System.out.println("HashMap存值"+map);
}
}
